const express = require('express');
const cors = require('cors');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { db, initDb } = require('./database.js');
const { verifyToken, JWT_SECRET } = require('./auth.js');

const app = express();
const PORT = process.env.PORT || 3001;

let isInitialSetup = false;

// 中间件
app.use(cors());
app.use(express.json());

// 静态文件服务，用于提供上传的图片
const uploadsDir = path.join(__dirname, 'public/uploads');
if (!fs.existsSync(uploadsDir)){
    fs.mkdirSync(uploadsDir, { recursive: true });
}
app.use('/uploads', express.static(uploadsDir));

// Multer 配置
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, uploadsDir);
    },
    filename: function (req, file, cb) {
        cb(null, Date.now() + path.extname(file.originalname)); // 时间戳命名，避免重名
    }
});
const fileFilter = (req, file, cb) => {
    const allowedTypes = /jpeg|jpg|png|webp/;
    const mimetype = allowedTypes.test(file.mimetype);
    const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
    if (mimetype && extname) {
        return cb(null, true);
    }
    cb(new Error("Error: File upload only supports the following filetypes - " + allowedTypes));
};

const upload = multer({
    storage: storage,
    limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
    fileFilter: fileFilter
});

// 将检查逻辑也 Promise 化，以便在 async 函数中使用
const checkInitialSetup = () => {
    return new Promise((resolve, reject) => {
        db.get("SELECT COUNT(*) as count FROM users", (err, row) => {
            if (err) {
                console.error("Failed to query users table:", err.message);
                return reject(err);
            }
            
            if (row.count === 0) {
                console.log("No superuser found. Application is in initial setup mode.");
                isInitialSetup = true;
            } else {
                console.log("Superuser exists. Running in normal mode.");
                isInitialSetup = false;
            }
            resolve();
        });
    });
};

// API 路由
app.get('/api/status', (req, res) => {
    res.json({
        message: "Welcome to the Blog API!",
        initialSetupRequired: isInitialSetup
    });
});

app.post('/api/register', (req, res) => {
    if (!isInitialSetup) {
        return res.status(403).json({ message: "Initial setup has already been completed." });
    }

    const { username, password } = req.body;

    if (!username || !password) {
        return res.status(400).json({ message: "Username and password are required." });
    }

    const saltRounds = 10;
    bcrypt.hash(password, saltRounds, (err, hash) => {
        if (err) {
            console.error("Error hashing password:", err);
            return res.status(500).json({ message: "Server error during password processing." });
        }

        const sql = "INSERT INTO users (username, password_hash) VALUES (?, ?)";
        db.run(sql, [username, hash], function(err) {
            if (err) {
                console.error("Error saving user to database:", err);
                return res.status(500).json({ message: "Database error while creating user." });
            }
            console.log(`Superuser ${username} created with ID: ${this.lastID}`);
            isInitialSetup = false;
            res.status(201).json({ message: "Superuser created successfully." });
        });
    });
});

// 用户登录
app.post('/api/login', (req, res) => {
    const { username, password } = req.body;
    if (!username || !password) {
        return res.status(400).json({ message: "Username and password are required." });
    }

    const sql = "SELECT * FROM users WHERE username = ?";
    db.get(sql, [username], (err, user) => {
        if (err) {
            return res.status(500).json({ message: "Database error." });
        }
        if (!user) {
            return res.status(401).json({ message: "Invalid credentials." });
        }

        bcrypt.compare(password, user.password_hash, (err, result) => {
            if (err || !result) {
                return res.status(401).json({ message: "Invalid credentials." });
            }

            const tokenPayload = { id: user.id, username: user.username };
            const token = jwt.sign(tokenPayload, JWT_SECRET, { expiresIn: '1d' }); // Token 有效期为 1 天

            res.json({ message: "Login successful.", token: token });
        });
    });
});

// 修改密码 (受保护的路由)
app.put('/api/user/password', verifyToken, (req, res) => {
    const { newPassword } = req.body;
    if (!newPassword) {
        return res.status(400).json({ message: "New password is required." });
    }

    const saltRounds = 10;
    bcrypt.hash(newPassword, saltRounds, (err, hash) => {
        if (err) {
            return res.status(500).json({ message: "Server error during password processing." });
        }

        const sql = "UPDATE users SET password_hash = ? WHERE id = ?";
        db.run(sql, [hash, req.user.id], function(err) {
            if (err) {
                return res.status(500).json({ message: "Database error while updating password." });
            }
            res.json({ message: "Password updated successfully." });
        });
    });
});

// --- 文章 API ---

// 获取所有文章
app.get('/api/posts', (req, res) => {
    db.all("SELECT id, title, created_at, updated_at FROM posts ORDER BY created_at DESC", [], (err, rows) => {
        if (err) return res.status(500).json({ message: "Database error." });
        res.json(rows);
    });
});

// 获取单篇文章
app.get('/api/posts/:id', (req, res) => {
    db.get("SELECT * FROM posts WHERE id = ?", [req.params.id], (err, row) => {
        if (err) return res.status(500).json({ message: "Database error." });
        if (!row) return res.status(404).json({ message: "Post not found." });
        res.json(row);
    });
});

// 创建新文章
app.post('/api/posts', verifyToken, (req, res) => {
    const { title, content_markdown } = req.body;
    if (!title || !content_markdown) {
        return res.status(400).json({ message: "Title and content are required." });
    }
    const sql = "INSERT INTO posts (title, content_markdown) VALUES (?, ?)";
    db.run(sql, [title, content_markdown], function(err) {
        if (err) return res.status(500).json({ message: "Database error." });
        res.status(201).json({ id: this.lastID, title, content_markdown });
    });
});

// 更新文章
app.put('/api/posts/:id', verifyToken, (req, res) => {
    const { title, content_markdown } = req.body;
    if (!title || !content_markdown) {
        return res.status(400).json({ message: "Title and content are required." });
    }
    const sql = "UPDATE posts SET title = ?, content_markdown = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?";
    db.run(sql, [title, content_markdown, req.params.id], function(err) {
        if (err) return res.status(500).json({ message: "Database error." });
        if (this.changes === 0) return res.status(404).json({ message: "Post not found." });
        res.json({ message: "Post updated successfully." });
    });
});

// 删除文章
app.delete('/api/posts/:id', verifyToken, (req, res) => {
    db.run("DELETE FROM posts WHERE id = ?", [req.params.id], function(err) {
        if (err) return res.status(500).json({ message: "Database error." });
        if (this.changes === 0) return res.status(404).json({ message: "Post not found." });
        res.status(204).send(); // No Content
    });
});

// --- 图片上传 API ---
// 用于文章内图片
app.post('/api/upload', verifyToken, upload.single('image'), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ message: "No file uploaded." });
    }
    // 返回图片的相对路径
    res.json({ url: `/uploads/${req.file.filename}` });
});



// --- 设置 API ---

// 获取所有设置
app.get('/api/settings', (req, res) => {
    db.all("SELECT key, value FROM settings", [], (err, rows) => {
        if (err) return res.status(500).json({ message: "Database error." });
        const settings = rows.reduce((acc, row) => {
            acc[row.key] = row.value;
            return acc;
        }, {});
        res.json(settings);
    });
});

// 更新设置
app.put('/api/settings', verifyToken, (req, res) => {
    const settings = req.body;
    const sql = "INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)";
    
    db.serialize(() => {
        db.run("BEGIN TRANSACTION");
        for (const key in settings) {
            db.run(sql, [key, settings[key]]);
        }
        db.run("COMMIT", (err) => {
            if (err) {
                db.run("ROLLBACK");
                return res.status(500).json({ message: "Failed to update settings." });
            }
            res.json({ message: "Settings updated successfully." });
        });
    });
});


// --- Production-only Static File Serving ---
// This block must be defined AFTER all API routes.
if (process.env.NODE_ENV === 'production') {
    const frontendDist = path.resolve(__dirname, '../frontend/dist');
    
    // 1. 优先服务静态资源 (JS, CSS, images, etc.)
    app.use(express.static(frontendDist));

    // 2. 对于所有其他非API请求，返回前端应用的入口点 (index.html)。
    // 这是服务单页应用 (SPA) 的标准“全匹配”路由。
    app.get(/^(?!\/api).*/, (req, res) => {
        const indexHtmlPath = path.resolve(frontendDist, 'index.html');
        
        // 最终解决方案：手动读取文件并发送，彻底绕过 res.sendFile 的底层BUG。
        fs.readFile(indexHtmlPath, (err, data) => {
            if (err) {
                console.error(`[ULTIMATE FATAL] Could not read index.html at ${indexHtmlPath}:`, err);
                res.status(500).send('Server failed to read the application file.');
                return;
            }
            res.setHeader('Content-Type', 'text/html');
            res.send(data);
        });
    });
}

// 启动服务器的异步函数
const startServer = async () => {
    try {
        // 1. 确保数据库和表已就绪
        await initDb();
        console.log("Database tables initialized successfully.");

        // 2. 检查是否存在超级用户
        await checkInitialSetup();

        // 3. 启动 Express 服务器
        app.listen(PORT, () => {
            console.log(`Server is running on http://localhost:${PORT}`);
        });
    } catch (error) {
        console.error("Failed to start the server:", error.message);
        process.exit(1); // 启动失败，退出进程
    }
};

// 执行启动
startServer();